<template>
  <!-- 新增/修改菜单的弹窗 -->
  <el-dialog :title="dialogTitle" v-model="dialogVisible" :width="700" class="custom-dialog" @close="closeDialog(menuFormRef)">
    <el-form ref="menuFormRef" :model="formData" :rules="rules" :label-width="formLabelWidth">
      <el-form-item label="角色名称" prop="roleName">
        <el-input v-model="formData.roleName" placeholder="请输入角色名称"></el-input>
      </el-form-item>
      <el-form-item label="角色标识" prop="roleCode">
        <el-input v-model="formData.roleCode" placeholder="请输入角色标识"></el-input>
      </el-form-item>
      <el-form-item label="角色排序" prop="sortOrder">
        <el-input-number style="width: 100%" v-model="formData.sortOrder" :min="0" controls-position="right">
          <template #decrease-icon>
            <el-icon>
              <Minus />
            </el-icon>
          </template>
          <template #increase-icon>
            <el-icon>
              <Plus />
            </el-icon>
          </template>
        </el-input-number>
      </el-form-item>
      <el-form-item label="角色状态" prop="isEnable">
        <el-switch
          v-model="formData.isEnable"
          active-text="正常"
          inactive-text="停用"
          :active-value="1"
          :inactive-value="0"
        ></el-switch>
      </el-form-item>
      <el-form-item label="菜单权限" prop="menus">
        <div class="w-full">
          <div>
            <el-checkbox v-model="expendAll" @change="setMenuOpenOrClose">折叠/展开</el-checkbox>
            <el-checkbox v-model="checkAll" @change="setMenuCheck">全选/全不选</el-checkbox>
          </div>
          <div class="border border-br-light rounded p-2 box-border">
            <el-tree
              ref="treeRef"
              :data="menuTreeData"
              show-checkbox
              :default-checked-keys="formData.menus"
              node-key="id"
              highlight-current
              :render-after-expand="false"
              :props="{ label: 'name', children: 'children' }"
            />
          </div>
        </div>
      </el-form-item>
      <el-form-item label="备注" prop="description">
        <el-input v-model="formData.description" placeholder="请输入备注"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button type="default" @click="closeDialog(menuFormRef)"> 取消 </el-button>
      <el-button type="primary" :loading="submitLoading" @click="handleSave(menuFormRef)"> 保存 </el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts" name="MenuAdd">
import { ElMessage, ElTree, FormInstance, FormRules } from "element-plus";
import { getMenuTreeList } from "@/api/modules/menu";
import { Role } from "@/api/interface/index";
import { createRole, updateRole } from "@/api/modules/role";
import { useComponentRef } from "@/hooks/useComponentRef";

const emits = defineEmits(["close"]);
const formLabelWidth = "100px";
const dialogTitle = ref("新增角色");
const dialogVisible = ref(false);
const expendAll = ref(false);
const checkAll = ref(false);
const menuFormRef = ref<FormInstance>();
const treeRef = useComponentRef(ElTree);
const submitLoading = ref(false);
const formData = reactive<Role.IRole>({
  roleName: "",
  roleCode: "",
  sortOrder: 0,
  isEnable: 1,
  menus: [],
  description: ""
});

const rules = ref<FormRules<Role.IRole>>({
  roleName: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
  roleCode: [{ required: true, message: "请输入角色标识", trigger: "blur" }]
});

const menuTreeData = ref([]);
const openDialog = async (type = "add", data: any = {}) => {
  dialogTitle.value = type === "edit" ? "修改角色" : "新增角色";
  if (type === "edit") {
    console.log(data);
    formData.id = data.id;
    formData.roleName = data.name;
    formData.roleCode = data.roleCode;
    formData.sortOrder = data.sortOrder;
    formData.isEnable = data.isEnable;
    formData.menus = data.menus;
    formData.description = data.description;
  }
  await getAllMenu();
  dialogVisible.value = true;
};

const getAllMenu = async () => {
  // 获取所有菜单
  const { data } = await getMenuTreeList();
  menuTreeData.value = data;

  // 判断当前菜单是否已经全选
  const ids = _getIds(data);
  checkAll.value = formData.menus?.length === ids.length;
};

const handleSave = (formRef: FormInstance | undefined) => {
  if (!formRef) return;
  submitLoading.value = true;

  formRef.validate(async (valid: boolean) => {
    if (valid) {
      try {
        const menuIds = treeRef.value?.getCheckedKeys() as number[];
        const saveURL = formData.id ? updateRole : createRole;
        await saveURL({
          ...formData,
          menus: menuIds
        });
        ElMessage.success("保存成功");
        closeDialog(formRef);
        submitLoading.value = false;
      } catch (error) {
        submitLoading.value = false;
      }
    } else {
      submitLoading.value = false;
    }
  });

  // 保存逻辑
};

const _getIds = (data: any) => {
  const ids: any[] = [];
  data.forEach((item: any) => {
    ids.push(item.id);
    if (item.children && item.children.length > 0) {
      ids.push(..._getIds(item.children));
    }
  });
  return ids;
};

const setMenuOpenOrClose = () => {
  const ids = _getIds(menuTreeData.value);
  ids.forEach((id: any) => {
    if (treeRef.value?.store.nodesMap[id]) {
      treeRef.value.store.nodesMap[id].expanded = expendAll.value;
    }
  });
};
const setMenuCheck = () => {
  const ids = _getIds(menuTreeData.value);
  treeRef.value?.setCheckedKeys(checkAll.value ? ids : []);
};

const closeDialog = (formRef: FormInstance | undefined) => {
  if (!formRef) return;
  formRef.resetFields();
  formData.id = undefined;
  dialogVisible.value = false;
  emits("close");
};
defineExpose({
  openDialog
});
</script>

<style scoped></style>
